package com.nl.lib_core.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.launcher.ARouter
import com.nl.lib_core.R
import com.nl.lib_core.event.core.BaseFragmentEvent
import com.nl.lib_core.mvp.IBaseView
import com.nl.lib_core.tool.NetUtil
import com.nl.lib_core.tool.log.KLog
import com.nl.lib_core.view.LoadingInitView
import com.nl.lib_core.view.NetErrorView
import com.nl.lib_core.view.NoDataView
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/** 作者: wangfei 创建时间: 2021/9/1 包名: com.nl.lib_core.base 类名: BaseFragment */
abstract class BaseFragment : Fragment(), IBaseView {

  protected lateinit var mActivity: AppCompatActivity
  protected lateinit var mView: View
  protected lateinit var mTxtTitle: TextView
  protected lateinit var mToolbar: Toolbar

  protected var mNetErrorView: NetErrorView? = null
  protected var mNoDataView: NoDataView? = null
  protected var mLoadingInitView: LoadingInitView? = null

  private lateinit var mViewStubToolbar: ViewStub
  private lateinit var mViewStubContent: ViewStub
  private lateinit var mViewStubInitLoading: ViewStub
  private lateinit var mViewStubNoData: ViewStub
  private lateinit var mViewStubError: ViewStub
  private var isViewCreated = false
  private var isViewVisible = false

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    mActivity = (activity as AppCompatActivity?)!!
    ARouter.getInstance().inject(this)
    EventBus.getDefault().register(this)
  }

  override fun onCreateView(
      inflater: LayoutInflater,
      container: ViewGroup?,
      savedInstanceState: Bundle?
  ): View? {
    mView = inflater.inflate(R.layout.core_fragment_root, container, false)
    initCommonView(mView)
    return mView
  }

  open fun initCommonView(view: View) {
    mViewStubToolbar = view.findViewById(R.id.view_stub_toolbar)
    mViewStubContent = view.findViewById(R.id.view_stub_content)
    mViewStubContent = view.findViewById(R.id.view_stub_content)
    mViewStubInitLoading = view.findViewById(R.id.view_stub_init_loading)
    mViewStubNoData = view.findViewById(R.id.view_stub_nodata)
    mViewStubError = view.findViewById(R.id.view_stub_error)

    if (enableToolbar()) {
      mViewStubToolbar.layoutResource = onBindToolbarLayout()
      val viewToolBar = mViewStubToolbar.inflate()
      initTooBar(viewToolBar)
    }
    mViewStubContent.layoutResource = onBindLayout()
    mViewStubContent.inflate()
  }

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    initListener()
    isViewCreated = true
    // 如果启用了懒加载就进行懒加载，否则就进行预加载
    if (enableLazyData()) {
      lazyLoad()
    } else {
      initData()
    }
  }

  override fun setUserVisibleHint(isVisibleToUser: Boolean) {
    super.setUserVisibleHint(isVisibleToUser)
    isViewVisible = isVisibleToUser
    // 如果启用了懒加载就进行懒加载，
    if (enableLazyData() && isViewVisible) {
      lazyLoad()
    }
  }

  private fun lazyLoad() {
    // 这里进行双重标记判断,必须确保onCreateView加载完毕且页面可见,才加载数据
    KLog.v("MYTAG", "lazyLoad start...")
    KLog.v("MYTAG", "isViewCreated:$isViewCreated")
    KLog.v("MYTAG", "isViewVisable$isViewVisible")
    if (isViewCreated && isViewVisible) {
      initData()
      // 数据加载完毕,恢复标记,防止重复加载
      isViewCreated = false
      isViewVisible = false
    }
  }

  /** 默认不启用懒加载 */
  open fun enableLazyData(): Boolean {
    return false
  }

  override fun onDestroy() {
    super.onDestroy()
    EventBus.getDefault().unregister(this)
  }

  private fun initTooBar(view: View) {
    mToolbar = view.findViewById(R.id.toolbar_root)
    mTxtTitle = view.findViewById(R.id.toolbar_title)
    mToolbar.let {
      mActivity.setSupportActionBar(mToolbar)
      mActivity.supportActionBar?.setDisplayShowTitleEnabled(false)
      mToolbar.setNavigationOnClickListener { mActivity.onBackPressed() }
    }
    mTxtTitle.let { it.text = getTootBarTitle() }
  }

  @Subscribe(threadMode = ThreadMode.MAIN) fun <T> onEvent(event: BaseFragmentEvent<T>) {}
  open fun getTootBarTitle(): String {
    return ""
  }
  abstract fun onBindLayout(): Int

  abstract override fun initData()

  override fun initListener() {}

  override fun finishActivity() {
    mActivity.finish()
  }

  fun enableToolbar(): Boolean {
    return false
  }

  open fun onBindToolbarLayout(): Int {
    return R.layout.core_common_toolbar
  }

  override fun showInitLoadView() {
    showInitLoadView(true)
  }

  override fun hideInitLoadView() {
    showInitLoadView(false)
  }

  override fun showNoDataView() {
    showNoDataView(true)
  }

  override fun showNoDataView(resid: Int) {
    showNoDataView(true, resid)
  }

  override fun hideNoDataView() {
    showNoDataView(false)
  }

  override fun showNetWorkErrView() {
    showNetWorkErrView(true)
  }

  override fun hideNetWorkErrView() {
    showNetWorkErrView(false)
  }

  private fun showInitLoadView(show: Boolean) {
    if (mLoadingInitView == null) {
      val view = mViewStubInitLoading.inflate()
      mLoadingInitView = view.findViewById(R.id.view_init_loading)
    }
    mLoadingInitView?.visibility = if (show) View.VISIBLE else View.GONE
  }

  private fun showNetWorkErrView(show: Boolean) {
    if (mNetErrorView == null) {
      val view = mViewStubError.inflate()
      mNetErrorView = view.findViewById(R.id.view_net_error)
      mNetErrorView?.setOnClickListener(
          View.OnClickListener {
            if (!NetUtil.checkNetToast()) {
              return@OnClickListener
            }
            hideNetWorkErrView()
            initData()
          })
    }
    mNetErrorView?.visibility = if (show) View.VISIBLE else View.GONE
  }

  private fun showNoDataView(show: Boolean) {
    if (mNoDataView == null) {
      val view = mViewStubNoData.inflate()
      mNoDataView = view.findViewById(R.id.view_no_data)
    }
    mNoDataView?.visibility = if (show) View.VISIBLE else View.GONE
  }

  private fun showNoDataView(show: Boolean, resId: Int) {
    showNoDataView(show)
    if (show) {
      mNoDataView?.setNoDataView(resId)
    }
  }

  companion object {
    protected val TAG = BaseFragment::class.java.simpleName
  }
}
